package com.pethospital.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pethospital.common.Result;
import com.pethospital.dto.ConversationDTO;
import com.pethospital.dto.ConversationVO;
import com.pethospital.dto.MessageDTO;
import com.pethospital.entity.Conversation;
import com.pethospital.entity.Message;
import com.pethospital.service.ConsultService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.handler.annotation.DestinationVariable;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 在线咨询控制器
 */
@Slf4j
@RestController
@RequestMapping("/consult")
public class ConsultController {

    @Resource
    private ConsultService consultService;

    @Resource
    private SimpMessagingTemplate messagingTemplate;

    /**
     * 创建会话
     */
    @PostMapping("/conversation")
    public Result<Long> createConversation(@RequestBody ConversationDTO conversationDTO, HttpServletRequest request) {
        log.info("创建会话请求，staffId: {}", conversationDTO.getStaffId());
        
        try {
            // 安全地从request attribute中获取userId
            Object userIdObj = request.getAttribute("userId");
            log.info("从请求中获取userId，类型: {}, 值: {}", userIdObj != null ? userIdObj.getClass().getName() : "null", userIdObj);
            
            Long userId = null;
            if (userIdObj instanceof Integer) {
                userId = ((Integer) userIdObj).longValue();
                log.info("userId转换为Long: {}", userId);
            } else if (userIdObj instanceof Long) {
                userId = (Long) userIdObj;
                log.info("userId已是Long类型: {}", userId);
            } else if (userIdObj != null) {
                try {
                    userId = Long.valueOf(userIdObj.toString());
                    log.info("userId从其他类型转换为Long: {}", userId);
                } catch (NumberFormatException e) {
                    log.error("userId转换Long失败: {}", userIdObj, e);
                }
            }
            
            if (userId == null) {
                log.warn("userId为空，用户未登录或会话已过期");
                return Result.error("用户未登录或会话已过期");
            }
            
            Long staffId = conversationDTO.getStaffId();
            log.info("准备创建会话，userId: {}, staffId: {}", userId, staffId);
            
            Long conversationId = consultService.createConversation(userId, staffId);
            log.info("会话创建成功，conversationId: {}", conversationId);
            
            return Result.success(conversationId);
        } catch (Exception e) {
            log.error("创建会话异常", e);
            return Result.error("创建会话失败: " + e.getMessage());
        }
    }

    /**
     * 结束会话
     */
    @PostMapping("/conversation/end/{id}")
    public Result<Void> endConversation(@PathVariable Long id, HttpServletRequest request) {
        log.info("结束会话请求，会话ID: {}", id);
        
        try {
            // 安全地从request attribute中获取userId
            Object userIdObj = request.getAttribute("userId");
            log.info("从请求中获取userId，类型: {}, 值: {}", userIdObj != null ? userIdObj.getClass().getName() : "null", userIdObj);
            
            Long userId = null;
            if (userIdObj instanceof Integer) {
                userId = ((Integer) userIdObj).longValue();
                log.info("userId转换为Long: {}", userId);
            } else if (userIdObj instanceof Long) {
                userId = (Long) userIdObj;
                log.info("userId已是Long类型: {}", userId);
            } else if (userIdObj != null) {
                try {
                    userId = Long.valueOf(userIdObj.toString());
                    log.info("userId从其他类型转换为Long: {}", userId);
                } catch (NumberFormatException e) {
                    log.error("userId转换Long失败: {}", userIdObj, e);
                }
            }
            
            if (userId == null) {
                log.warn("userId为空，用户未登录或会话已过期");
                return Result.error("用户未登录或会话已过期");
            }
            
            consultService.endConversation(id, userId);
            log.info("会话结束成功，会话ID: {}", id);
            
            return Result.success();
        } catch (Exception e) {
            log.error("结束会话异常", e);
            return Result.error("结束会话失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户的会话列表
     */
    @GetMapping("/conversation/user")
    public Result<List<ConversationVO>> getUserConversations(HttpServletRequest request) {
        log.info("获取用户会话列表请求");
        
        try {
            // 安全地从request attribute中获取userId
            Object userIdObj = request.getAttribute("userId");
            log.info("从请求中获取userId，类型: {}, 值: {}", userIdObj != null ? userIdObj.getClass().getName() : "null", userIdObj);
            
            Long userId = null;
            if (userIdObj instanceof Integer) {
                userId = ((Integer) userIdObj).longValue();
                log.info("userId转换为Long: {}", userId);
            } else if (userIdObj instanceof Long) {
                userId = (Long) userIdObj;
                log.info("userId已是Long类型: {}", userId);
            } else if (userIdObj != null) {
                try {
                    userId = Long.valueOf(userIdObj.toString());
                    log.info("userId从其他类型转换为Long: {}", userId);
                } catch (NumberFormatException e) {
                    log.error("userId转换Long失败: {}", userIdObj, e);
                }
            }
            
            if (userId == null) {
                log.warn("userId为空，用户未登录或会话已过期");
                return Result.error("用户未登录或会话已过期");
            }
            
            List<ConversationVO> conversations = consultService.getUserConversations(userId);
            log.info("获取用户会话列表成功，count: {}", conversations.size());
            
            return Result.success(conversations);
        } catch (Exception e) {
            log.error("获取用户会话列表异常", e);
            return Result.error("获取会话列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取医护人员的会话列表
     */
    @GetMapping("/conversation/staff")
    public Result<List<ConversationVO>> getStaffConversations(HttpServletRequest request) {
        log.info("获取医护人员会话列表请求");
        
        try {
            // 安全地从request attribute中获取staffId
            Object userIdObj = request.getAttribute("userId");
            log.info("从请求中获取userId(staffId)，类型: {}, 值: {}", userIdObj != null ? userIdObj.getClass().getName() : "null", userIdObj);
            
            Long staffId = null;
            if (userIdObj instanceof Integer) {
                staffId = ((Integer) userIdObj).longValue();
                log.info("staffId转换为Long: {}", staffId);
            } else if (userIdObj instanceof Long) {
                staffId = (Long) userIdObj;
                log.info("staffId已是Long类型: {}", staffId);
            } else if (userIdObj != null) {
                try {
                    staffId = Long.valueOf(userIdObj.toString());
                    log.info("staffId从其他类型转换为Long: {}", staffId);
                } catch (NumberFormatException e) {
                    log.error("staffId转换Long失败: {}", userIdObj, e);
                }
            }
            
            if (staffId == null) {
                log.warn("staffId为空，用户未登录或会话已过期");
                return Result.error("用户未登录或会话已过期");
            }
            
            List<ConversationVO> conversations = consultService.getStaffConversations(staffId);
            log.info("获取医护人员会话列表成功，count: {}", conversations.size());
            
            return Result.success(conversations);
        } catch (Exception e) {
            log.error("获取医护人员会话列表异常", e);
            return Result.error("获取会话列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取会话消息历史
     */
    @GetMapping("/message/{conversationId}")
    public Result<Page<Message>> getMessages(
            @PathVariable Long conversationId,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "20") int size,
            HttpServletRequest request) {
        log.info("获取会话消息历史请求，会话ID: {}, page: {}, size: {}", conversationId, page, size);
        
        try {
            // 安全地从request attribute中获取userId
            Object userIdObj = request.getAttribute("userId");
            log.info("从请求中获取userId，类型: {}, 值: {}", userIdObj != null ? userIdObj.getClass().getName() : "null", userIdObj);
            
            Long userId = null;
            if (userIdObj instanceof Integer) {
                userId = ((Integer) userIdObj).longValue();
                log.info("userId转换为Long: {}", userId);
            } else if (userIdObj instanceof Long) {
                userId = (Long) userIdObj;
                log.info("userId已是Long类型: {}", userId);
            } else if (userIdObj != null) {
                try {
                    userId = Long.valueOf(userIdObj.toString());
                    log.info("userId从其他类型转换为Long: {}", userId);
                } catch (NumberFormatException e) {
                    log.error("userId转换Long失败: {}", userIdObj, e);
                }
            }
            
            if (userId == null) {
                log.warn("userId为空，用户未登录或会话已过期");
                return Result.error("用户未登录或会话已过期");
            }
            
            Page<Message> messages = consultService.getMessages(conversationId, userId, page, size);
            log.info("获取会话消息历史成功，会话ID: {}，消息数: {}", conversationId, messages.getRecords().size());
            
            return Result.success(messages);
        } catch (Exception e) {
            log.error("获取会话消息历史异常", e);
            return Result.error("获取消息历史失败: " + e.getMessage());
        }
    }

    /**
     * 标记消息为已读
     */
    @PostMapping("/message/read/{conversationId}")
    public Result<Void> readMessages(@PathVariable Long conversationId, HttpServletRequest request) {
        log.info("标记消息为已读请求，会话ID: {}", conversationId);
        
        try {
            // 安全地从request attribute中获取userId
            Object userIdObj = request.getAttribute("userId");
            log.info("从请求中获取userId，类型: {}, 值: {}", userIdObj != null ? userIdObj.getClass().getName() : "null", userIdObj);
            
            Long userId = null;
            if (userIdObj instanceof Integer) {
                userId = ((Integer) userIdObj).longValue();
                log.info("userId转换为Long: {}", userId);
            } else if (userIdObj instanceof Long) {
                userId = (Long) userIdObj;
                log.info("userId已是Long类型: {}", userId);
            } else if (userIdObj != null) {
                try {
                    userId = Long.valueOf(userIdObj.toString());
                    log.info("userId从其他类型转换为Long: {}", userId);
                } catch (NumberFormatException e) {
                    log.error("userId转换Long失败: {}", userIdObj, e);
                }
            }
            
            if (userId == null) {
                log.warn("userId为空，用户未登录或会话已过期");
                return Result.error("用户未登录或会话已过期");
            }
            
            consultService.readMessages(conversationId, userId);
            log.info("标记消息为已读成功，会话ID: {}", conversationId);
            
            return Result.success();
        } catch (Exception e) {
            log.error("标记消息为已读异常", e);
            return Result.error("标记消息已读失败: " + e.getMessage());
        }
    }

    /**
     * 发送消息（HTTP方式）
     */
    @PostMapping("/message/{conversationId}")
    public Result<Message> sendMessage(@PathVariable Long conversationId, @RequestBody MessageDTO messageDTO, HttpServletRequest request) {
        log.info("HTTP方式发送消息请求，会话ID: {}, 发送者ID: {}, 内容长度: {}", 
                conversationId, messageDTO.getSenderId(), 
                messageDTO.getContent() != null ? messageDTO.getContent().length() : 0);
        
        try {
            // 安全地从request attribute中获取userId
            Object userIdObj = request.getAttribute("userId");
            log.info("从请求中获取userId，类型: {}, 值: {}", userIdObj != null ? userIdObj.getClass().getName() : "null", userIdObj);
            
            Long userId = null;
            if (userIdObj instanceof Integer) {
                userId = ((Integer) userIdObj).longValue();
                log.info("userId转换为Long: {}", userId);
            } else if (userIdObj instanceof Long) {
                userId = (Long) userIdObj;
                log.info("userId已是Long类型: {}", userId);
            } else if (userIdObj != null) {
                try {
                    userId = Long.valueOf(userIdObj.toString());
                    log.info("userId从其他类型转换为Long: {}", userId);
                } catch (NumberFormatException e) {
                    log.error("userId转换Long失败: {}", userIdObj, e);
                }
            }
            
            if (userId == null) {
                log.warn("userId为空，用户未登录或会话已过期");
                return Result.error("用户未登录或会话已过期");
            }
            
            // 设置发送者信息（如果客户端未提供）
            if (messageDTO.getSenderId() == null) {
                messageDTO.setSenderId(userId);
                log.info("设置消息发送者ID: {}", userId);
            }
            
            if (messageDTO.getSenderType() == null) {
                Integer userType = (Integer) request.getAttribute("userType");
                messageDTO.setSenderType(userType != null && userType == 2 ? 1 : 0); // 1=医生, 0=普通用户
                log.info("设置消息发送者类型: {}", messageDTO.getSenderType());
            }
            
            // 保存消息
            Message message = consultService.saveMessage(conversationId, messageDTO);
            log.info("HTTP方式消息保存成功，消息ID: {}", message.getId());
            
            // 通过WebSocket推送消息给订阅者
            messagingTemplate.convertAndSend("/topic/conversation/" + conversationId, message);
            log.info("消息已通过WebSocket推送，会话ID: {}", conversationId);
            
            return Result.success(message);
        } catch (Exception e) {
            log.error("发送消息异常", e);
            return Result.error("发送消息失败: " + e.getMessage());
        }
    }

    /**
     * WebSocket发送消息
     */
    @MessageMapping("/conversation/{conversationId}")
    public void sendMessage(@DestinationVariable Long conversationId, MessageDTO messageDTO) {
        log.info("通过WebSocket接收到消息: 会话ID={}, 发送者类型={}, 发送者ID={}, 内容长度={}",
                conversationId, messageDTO.getSenderType(), messageDTO.getSenderId(), 
                messageDTO.getContent() != null ? messageDTO.getContent().length() : 0);
        
        try {
            // 保存消息
            Message message = consultService.saveMessage(conversationId, messageDTO);
            if (message != null) {
                log.info("消息保存成功: 消息ID={}", message.getId());
                
                // 推送消息给订阅者
                messagingTemplate.convertAndSend("/topic/conversation/" + conversationId, message);
                log.info("消息推送成功: 会话ID={}", conversationId);
            } else {
                log.error("消息保存失败: 会话ID={}", conversationId);
            }
        } catch (Exception e) {
            log.error("处理WebSocket消息异常: 会话ID=" + conversationId, e);
        }
    }

    /**
     * 获取医护人员咨询统计
     */
    @GetMapping("/statistics/staff")
    public Result<Map<String, Object>> getStaffConsultationStatistics(
            @RequestParam(required = false) Long staffId,
            HttpServletRequest request) {
        log.info("获取医护人员咨询统计请求");
        
        try {
            // 获取staffId
            if (staffId == null) {
                Object userIdObj = request.getAttribute("userId");
                if (userIdObj instanceof Long) {
                    staffId = (Long) userIdObj;
                } else if (userIdObj instanceof Integer) {
                    staffId = ((Integer) userIdObj).longValue();
                } else if (userIdObj != null) {
                    staffId = Long.valueOf(userIdObj.toString());
                }
            }
            
            if (staffId == null) {
                log.warn("staffId为空，用户未登录或会话已过期");
                return Result.error("用户未登录或会话已过期");
            }
            
            // 统计数据
            // 这里可以改为实际调用service层来获取真实数据
            Map<String, Object> statistics = new HashMap<>();
            
            // 查询医生的所有咨询会话
            List<ConversationVO> allConversations = consultService.getStaffConversations(staffId);
            int totalCount = allConversations.size();
            
            // 计算活跃会话数量（未结束的会话）
            int activeCount = 0;
            for (ConversationVO conversation : allConversations) {
                if (conversation.getStatus() != null && conversation.getStatus() == 0) {
                    activeCount++;
                }
            }
            
            statistics.put("totalCount", totalCount);
            statistics.put("activeCount", activeCount);
            
            log.info("获取医护人员咨询统计成功，total: {}, active: {}", totalCount, activeCount);
            
            return Result.success(statistics);
        } catch (Exception e) {
            log.error("获取医护人员咨询统计异常", e);
            // 返回默认值，避免前端报错
            Map<String, Object> defaultStats = new HashMap<>();
            defaultStats.put("totalCount", 0);
            defaultStats.put("activeCount", 0);
            return Result.success(defaultStats);
        }
    }
    
    /**
     * 获取医护人员最近咨询会话
     */
    @GetMapping("/conversation/staff/recent")
    public Result<List<Map<String, Object>>> getStaffRecentConversations(
            @RequestParam(required = false) Long staffId,
            @RequestParam(defaultValue = "5") int limit,
            HttpServletRequest request) {
        log.info("获取医护人员最近咨询会话请求，limit: {}", limit);
        
        try {
            // 获取staffId
            if (staffId == null) {
                Object userIdObj = request.getAttribute("userId");
                if (userIdObj instanceof Long) {
                    staffId = (Long) userIdObj;
                } else if (userIdObj instanceof Integer) {
                    staffId = ((Integer) userIdObj).longValue();
                } else if (userIdObj != null) {
                    staffId = Long.valueOf(userIdObj.toString());
                }
            }
            
            if (staffId == null) {
                log.warn("staffId为空，用户未登录或会话已过期");
                return Result.error("用户未登录或会话已过期");
            }
            
            // 获取医生的所有会话
            List<ConversationVO> allConversations = consultService.getStaffConversations(staffId);
            
            // 转换为前端需要的格式
            List<Map<String, Object>> result = new ArrayList<>();
            int count = 0;
            
            for (ConversationVO conversation : allConversations) {
                if (count >= limit) break;
                
                Map<String, Object> item = new HashMap<>();
                item.put("id", conversation.getId());
                // 提供默认值，避免空指针异常
                String userName = "用户" + conversation.getUserId();
                if (conversation.getUserName() != null && !conversation.getUserName().isEmpty()) {
                    userName = conversation.getUserName();
                }
                item.put("userName", userName);
                item.put("userAvatar", conversation.getUserAvatar());
                item.put("lastMessage", conversation.getLastMessage() != null ? 
                        conversation.getLastMessage() : "暂无消息");
                item.put("lastMessageTime", conversation.getLastMessageTime() != null ? 
                        conversation.getLastMessageTime() : conversation.getUpdateTime());
                item.put("status", conversation.getStatus());
                
                result.add(item);
                count++;
            }
            
            log.info("获取医护人员最近咨询会话成功，count: {}", result.size());
            
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取医护人员最近咨询会话异常", e);
            return Result.success(new ArrayList<>());
        }
    }
    
    /**
     * 创建医护人员与用户的会话
     */
    @PostMapping("/conversation/staff")
    public Result<Long> createStaffConversation(
            @RequestBody Map<String, Object> params,
            HttpServletRequest request) {
        log.info("创建医护人员与用户会话请求，params: {}", params);
        
        try {
            // 获取staffId
            Object userIdObj = request.getAttribute("userId");
            Long staffId = null;
            if (userIdObj instanceof Long) {
                staffId = (Long) userIdObj;
            } else if (userIdObj instanceof Integer) {
                staffId = ((Integer) userIdObj).longValue();
            } else if (userIdObj != null) {
                staffId = Long.valueOf(userIdObj.toString());
            }
            
            if (staffId == null) {
                log.warn("staffId为空，用户未登录或会话已过期");
                return Result.error("用户未登录或会话已过期");
            }
            
            // 获取userId
            Object userIdParam = params.get("userId");
            if (userIdParam == null) {
                log.warn("userId为空，无法创建会话");
                return Result.error("用户ID不能为空");
            }
            
            Long userId = null;
            if (userIdParam instanceof Long) {
                userId = (Long) userIdParam;
            } else if (userIdParam instanceof Integer) {
                userId = ((Integer) userIdParam).longValue();
            } else {
                userId = Long.valueOf(userIdParam.toString());
            }
            
            // 创建会话
            Long conversationId = consultService.createConversation(userId, staffId);
            log.info("创建医护人员与用户会话成功，conversationId: {}", conversationId);
            
            return Result.success(conversationId);
        } catch (Exception e) {
            log.error("创建医护人员与用户会话异常", e);
            return Result.error("创建会话失败: " + e.getMessage());
        }
    }
} 